#include "asyncsubscribe.h"
#include <unistd.h>

#include <uavtmi/uavtmi.pb.h>

AsyncSubscribe::AsyncSubscribe(const std::string name)
    :MqttClient()
    , m_pClient(NULL)
    , m_pSubListener(NULL)
    , m_pCb(NULL)
    , m_nameSubscribtion(name)
    , f_bExit(false)
{
    m_QOS = publish::AT_LEAST_ONCE;
    m_clientId = m_nameSubscribtion;

    m_pClient = new mqtt::async_client(m_address, m_clientId);
}

AsyncSubscribe::~AsyncSubscribe()
{
    if(m_pCb)
        delete m_pCb;

    if(m_pSubListener)
        delete m_pSubListener;

    if(m_pClient)
        delete m_pClient;
}

bool AsyncSubscribe::activate()
{
    async_subscribe_tools::action_listener subListener("Subscription");

    async_subscribe_tools::callback cb(*m_pClient, subListener);
    cb.initSubscribe(this);
    m_pClient->set_callback(cb);

    mqtt::connect_options connOpts;
    connOpts.set_keep_alive_interval(20);
    connOpts.set_clean_session(true);

    try {
        mqtt::itoken_ptr conntok = m_pClient->connect(connOpts);
        std::cout << "Waiting for the connection..." << std::flush;
        conntok->wait_for_completion();
        std::cout << "OK" << std::endl;

        m_pClient->subscribe(m_topic, m_QOS, nullptr, subListener);

        while (!f_bExit)
            ;

        std::cout << "Disconnecting..." << std::flush;
        conntok = m_pClient->disconnect();
        conntok->wait_for_completion();
        std::cout << "OK" << std::endl;
    }
    catch (const mqtt::exception& exc)
    {
        std::cerr << "Error: " << exc.what() << std::endl;
        return 1;
    }
    return true;
}


bool AsyncSubscribe::deactivate()
{
    f_bExit = true;
    return true;
}

void AsyncSubscribe::messageRecieved(const std::string &topic, std::string message)
{
    telemetry::Navigation nav;

    if(nav.ParseFromString(message))
    {
        QByteArray ba_top(topic.data(), topic.size()), ba_mes(message.data(), message.size());
        emit dataRecived(ba_top, ba_mes);
    }
}
